23

» WarCraft 3 / Проблемы с ИИ

Похожие вопросы:

ответ
Создай способность "Книга заклинаний". Туда кидай все способности, которые хочешь скрыть. Потом через действие "Игрок - Включить/Выключить способность" (SetPlayerAbilityAvailable) скрой этот спелбук. Иконок не будет, способности будут. А для описаний всех скилов - один создай, пустышку, или не пустышку. Но это всё касается пассивок. Незнаю как с активными скилами.
ответ
Меняешь расширение с .w3n на .mpq (хоть простым переименованием) и открываешь архив любым MPQ-едитором (лично я пользовался этим xgm.guru/p/wc3/ladiks-mpq). После экспортируешь оттуда нужную тебе карту.
ответ
В событиях и условии там -name с одним пробелом
ответ
Попробуй конвертировать через war3 image extracror, а в фш сохрани картинку как 32 битную. Ну и разумеется разрешение 512х512
Когда будешь вставлять в карту, закинь картинку в мапу , а еще тебе понадобится LoadScreen.mds. В свойствах карты на загрузочный экран установишь LoadScreen.mdx, ну это я так, на всякий случай. Саму картинку нужно назвать FullScreen.blp
ответ
~8gabriel8:
Добавь в текст ссылки на все файлы, только AnimLookups.slk могу скачать.


И длительность звука сократил, и не с первого кадра анимации, как и у Стрелка сделал, и поместил внутри war3x.mpq, а не просто в карту импортировал, и поместил звук в модели отдельно, как и у Стрелка, а не привязал к кости, и много чего ещё пробовал, но так и не воспроизводит звук, да.
Уже удалил всё, но сейчас пришло в голову, что может быть таблицы надо было не в war3x.mpq помещать, а в war3Patch.mpq. Только это вряд ли, потому что даже при импорте в карту ничего не было.

23

» WarCraft 3 / Положение вставки

Похожие вопросы:

ответ
На счет вставки не знаю, а поведение юнита устанавливается в Характеристики - Построение (ufor). 0 - первый ряд, 1 - второй и т. д.
ответ
Судя по всему - это некий приоритет. Т.е. если в одну казарму\магазин положишь несколько юнитов\предметов с указанным одинаковым местом расположения, то первым встанет тот, у которого положение вставки больше (а может меньше).
ответ
Отвечает за скорость поворота модели. Имеет лишь визуальный эффект.

23

» WarCraft 3 / Ищу разработчика для карты Лорды Европы за оплату!

Похожие вопросы:

ответ
Чисто для галочки:
Три года назад он мне уже писал.
Я ему поэтапно, с его "да/нет", сделал некий ряд изменений в скрипте карты.
По итогу я скинул ему карту, и он ответил мне - "Хорошо, я посмотрю и скину деньги"
С тех пор, он так ни разу и не написал...
Сейчас же, когда я ему об этом напомнил, он отвечает что-то типа "у меня нет переписки".
Я ему скопировал его же сообщения, от отвечает - "А, ну значит мне что-то не понравилось"
Имейте ввиду, кароче.

23

» WarCraft 3 / Как правильно добавлять иконки в карту?

Похожие вопросы:

ответ
Я понял, что процесс сделан как и "MPQEditor", но всё равно не доганяю. Объясните или киньте ссылку с объяснением, так как я не нашёл инфы на это.
тебе объяснили
прога редактирует файл
Я например не знаю как это делать.
статьи по с++/java/любойдругойяп ждут тебя
У меня такое впечатление складывается что ты со мной как с нубом разговариваешь.
тебе показалось (за исключением этого коммента)
Ок. Но лучше ответ бы, чем отправлять меня в тёмный лес. =(
это и есть ответ
если тебе надо
Напиши мне раз умный. Я например не знаю как это делать. И потом дай мне и инструкцию напиши к ней. =\
то ты ошибся адресом
это Q/A а не сделай всё за меня
тебе объяснили что надо редактировать и чем
что ещё тебе надо объяснить?
как печатать на клаве или как сохранять отредактированный файл?
BaHeK:
war3map.imp - бинарный файл и редактируют его не блокнотом, НЕХ-редактором. Ну и к тому-же там особая структура файла.
блокнот прекрасно справляется
короче ответ на вопрос дан (только злые люди прогу для автора не написали)
поэтому клоз
и контрольный в голову
статья про сабж

23

» WarCraft 3 / Ошибка редактора

Похожие вопросы:

ответ
Переделывайте юнитов, с нуля. Как и код подправьте, ид юнитов\предметов (да всего) это числа от N и до хрен знает сколько, это все данные в таблице, когда удаляете эти обьекты остаются незанятые ячейки, ну из 250 юнитов, осталось только 150, 100 ячеек пустые вот и багует редактор.
ответ
~8gabriel8:
Похоже, что либо cjass/vjass отключены в редакторе, либо карту сохраняешь по пути с кириллицей.
ответ
Ничего не понятно. pjass.exe никак не влияет на либы и скопы, это не его забота.

23

» WarCraft 3 / Движение по кругу

Похожие вопросы:

ответ
Ну вообще, такое делается с помощью алгоритма Грэхема по построению выпуклой оболочки.
ответ
проверил, все работает, всем спасибо)
в коде будет примерно такой вид:
function getTrajectoryRadius takes real speed, real rotationSpeed returns real
	local real  N = 360 / rotationSpeed		// количество сторон вписанного многоугольника
		return speed / (2 * (Sin (PI / N)))
endfunction
ответ
Я пробовал каналом с заданным приказом patrol. Когда отдаем приказ patrol, то получается что юнит не патрулирует, а бежит кастовать в точку, игноря всех. Я забил на этот способ. Потом пришла новая идея, а вдруг можно абузить этим способом. Представьте, сначала бежит патрулировать в одну точку, а когда дойдет, он же побежит обратно - получит другой приказ, и тут канал срабатывает, и мы узнаем завершение. Короче, не работает. Канал тоже не видит приказы patrol, только в начале
SomeFire, ну это понятно. Но мне хочется свою систему патрулирования иметь. Но чекать поиском весь маршрут на наличие противников и прочее, не хочется. Проще отловить начальные приказы patrol, далее ловим завершение приказа, и в завершении готовый patrol отдать в точку, дошел - отдаем новый patrol в точку. дело - отследить.
пока самый оптимальный вариант - это таймером чекать изменилось ли положение маршрута, там нужно интервал таймера сделать больше. И пока работает хорошо, но насколько хорошо - неизвестно. Но я еще забываю, что юниты могут драться, и в патруле могут остановиться и подраться. Ну придется заигнорить патрулирование.
patrol => заменить на attack - тут визуальные эффекты портят все. рамку как найти. можно кое-что сделать))

23

» WarCraft 3 / Глобальные переменные в Lua

Похожие вопросы:

ответ
В свойствах убери заголовочный файл и в линкере с настройками поиграй
ответ
Ответ выше - для стандартного редактора WE. Однако, рекомендуется использовать с Lua внешний редактор кода и внешний же сборщик карты. Это чревато маленьким неудобством в виде необходимости запускать карту на проверку только из внешней программы т.к. запуск из WE будет без значительной части кода в карте, но дает огромное преимущество в виде несравнимо более удобной работы с кодом.
К сожалению, пока слишком мало информации об этом на сайте.
Вариант NazarPunk, пока без сборки карты, код придется копировать в карту вручную.

Мой вариант, пока не рабочий т.к. перед релизом нужно исправить несколько багов, но включает в себя и работу с кодом и сборку карты, не нужно вручную копировать код в карту.
Даже здесь на сайте есть еще пара вариантов, но мне лень их искать
И немного саморекламы, как выглядели бы ответы на вопрос выше при использовании моего тулсета
  1. Использовать макрос RAW('A0E5'), который превратит равкод в число при сборке карты.
  2. Инжект в функцию main, с заменой оригинальной функции main на свою и вызовом оригинальной функции изнутри нашей.
  3. Аналогично ответу на этот вопрос для чистого WE, но без объявления переменных в WE т.к. то уже не так удобно становится когда код во внешнем редакторе.

Теперь о точках входа и инжекте.
Луа позволяет делать такой финт ушами
do
  local f = FunctionName -- записываем функцию в переменную
  function FunctionName() -- заменяем оригинальную функцию своей
   f() -- вызываем оригинальную функцию из переменной
   -- здесь могла быть ваша реклама или ваш код
  end
end
Это позволит нам сохранить оригинальную функцию в переменную, заменить оригинал своей функцией и вызвать оригинал из переменной. Применимо к любой функции, которая была объявлена раньше, не работает если функция объявлена после выполнения этого кода. Для создания точки входа отлично подходит InitGlobals, она всегда объявляется раньше кастомного кода в WE и вызывается из main.

У себя в коде я пользуюсь немного более сложным способом, этот код не будет работать в WE т.к. цепляет main, а не InitGlobals и не дает серьеных преимуществ перед описаным выше, привожу просто для расширения кругозора
local function InjectMain()
    local alpha_main = main
    return function()
        local alpha_init = RunInitializationTriggers
        RunInitializationTriggers = function() end
        alpha_main()
        InitLibraries() --моя функция, которая должна быть выполнена после всего, но до триггеров инициализации карты
        alpha_init()
    end
end
main = InjectMain()
ответ
gg_unit_hdhw_0001
hdhw - равкод юнита
0001 - его номер
Номер можешь посмотреть в менеджере объектов

upd: Выбираем юнита - Правка - Просмотр выборки - Просмотреть в менеджере объектов

upd1: хотя у меня нет рефорджа, вероятно там по другому

23

» WarCraft 3 / Дополнительные ресурсы

Похожие вопросы:

ответ
Ну, перенеси всё это clawbfs.ucoz.ru/forum/3-2-1 и итемы и две игровые карты с кучей режимов и сотни шапок и т. д. + в 2 раза больше новых идей clawbfs.ucoz.ru/forum/7 clawbfs.ucoz.ru/forum/16-1571-1 clawbfs.ucoz.ru/forum/9 со всеми функциями варкрафта (а их там всё же не так уж и мало) в игру на юнити или ещё куда в один присест, сделай дело доброе.
Бтв, про сбор команды - для продвинутых сущностей нередко исправлять за другими оказывается тяжелее, чем делать самому, важно создать максимально комфортные условия для созидания, вот для чего деньги не лишние, а уж дело и самому можно делать.
И, да, тема-то не про то, надо это или не надо, а про то, как лучше это сделать, я про это и в стартовом сообщении написал.
Я на крайний сам вопрос по варианту 3 проверю и/или будет сделан выбор между третьим вариантом, вторым, каким-то ещё и отказом от Cooldown Reduction, но если кто поможет - спасибо.
ответ
DemonoiD, Нет, да и лимит не всегда был 8 мб, недавно с четырёх подняли (относительно времени жизни варкравта).
Снова есть ретурн баг, подгружаешь микс архив всем кто запустил карту без их ведома и подключаешь, пусть улыбаются.
Правда могут быть проблемы с некоторыми античитами.
ответ
фотошопом же...
ответ
Я бы не стал играть в кампанию, автор которой называет ее кОмпания.

23

» WarCraft 3 / TriggerRegisterUnitInRange

Похожие вопросы:

ответ
Такого события нету. Оно в общем то не очень нужное, ибо можно просто использовать периодический триггер и сравнивать по содержанию юнитов в группах в разные периоды времени. Тут и вхождение, и выход из радиуса можно сделать.
ответ
native TriggerRegisterUnitInRange takes trigger whichTrigger, unit whichUnit, real range, boolexpr filter returns event
whichUnit - тот самый юнит. В идеале, его нужно хранить в переменной, чтобы обращаться к нему снова.
Соответственно, ответом на вопрос
а как называть того что мейн?
будет:
Как хочешь))00
ответ
ой сорь, забыл малость, там не событе а функция с похожим названием:
Прикладываю пример, чтобы потом не ныли что не работает...
ответ
таймер я так понимаю глобальный делать ?
да. смотри чтоб менее утечный был, на гуи все действия мб утечны с группами
ответ
ResetTrigger сбрасывает счетчик срабатываний Action/Condition, всё

23

» WarCraft 3 / Как импортировать

Похожие вопросы:

ответ
Редактор объектов, функция «Экспорт всех данных». Делает файл со всеми нестандартными объектами карты. Вот их-то и можно импортировать.
ответ
~8gabriel8:
MrSlendyBoy, да чего ты пристал, не знаю если я? Искал бы видео, если его хочешь, а здесь помогают найти путь к решению проблемы, а не решают за тебя (иногда решают, когда быстрее сделать, чем объяснить, но надо уметь делать).
ответ
Нужные проги: Вовмолелвивер, 3дсмакс с плагинами на м2 и mdl и mdl>mdx конвентер.
Достаешь из Вивера модель в формате м2 и текстуру с расширением skin, импортируешь в Макс, сохраняешь в mdl формат, затем конвентируешь в mdx. На декор без анимации занимает 5 минут времени.
ответ
~8gabriel8:
В редакторе кампаний 4 вкладки, последняя для импорта. Импортируй туда модель с текстурами так, как и в карту.
ответ
Так же как и обычные модели. Но ДДС будет работать только в рефордже, на патче 126 ничего не получится, ссылку на модель в студию

Если надо могу все перегнать в блп и сделать модель рабочей на любом патче и любой графике

23

» WarCraft 3 / Вопрос по коду

Похожие вопросы:

ответ
Вам сюда, господин хороший. Там есть ответы, практически, на все ваши вопросы.
ответ
Wyett, ты можешь добавлять подобные этим:
function ... takes ... returns ...
Код
endfunction
Резака купить можно, но это будет абсолютно не похоже на покупку дирижабля.
ответ
А это ресайкл групп, кусок системы GroupUtils.
код
library GroupUtils
//******************************************************************************
//* BY: Rising_Dusk
//* 
//* This library is a simple implementation of a stack for groups that need to
//* be in the user's control for greater than an instant of time. Additionally,
//* this library provides a single, global group variable for use with user-end
//* enumerations. It is important to note that users should not be calling
//* DestroyGroup() on the global group, since then it may not exist for when it
//* it is next needed.
//*
//* The group stack removes the need for destroying groups and replaces it with
//* a recycling method.
//*     function NewGroup takes nothing returns group
//*     function ReleaseGroup takes group g returns boolean
//*     function GroupRefresh takes group g returns nothing
//* 
//* NewGroup grabs a currently unused group from the stack or creates one if the
//* stack is empty. You can use this group however you'd like, but always
//* remember to call ReleaseGroup on it when you are done with it. If you don't
//* release it, it will 'leak' and your stack may eventually overflow if you
//* keep doing that.
//* 
//* GroupRefresh cleans a group of any shadow references which may be clogging
//* its hash table. If you remove a unit from the game who is a member of a unit
//* group, it will 'effectively' remove the unit from the group, but leave a
//* shadow in its place. Calling GroupRefresh on a group will clean up any
//* shadow references that may exist within it.
//* 
globals
    //* Group for use with all instant enumerations
    group ENUM_GROUP = CreateGroup()
    
    //* Temporary references for GroupRefresh
    private boolean Flag                                              = false
    private group Refr                                                = null
    
    //* Assorted constants
    private constant integer MAX_HANDLE_COUNT                         = 408000
    private constant integer MIN_HANDLE_ID                            = 0x100000
    
    //* Arrays and counter for the group stack
    private group array Groups
    private integer array Status[MAX_HANDLE_COUNT]
    private integer Count                                             = 0
endglobals

private function AddEx takes nothing returns nothing
    if Flag then
        call GroupClear(Refr)
        set Flag = false
    endif
    call GroupAddUnit(Refr, GetEnumUnit())
endfunction
    
function GroupRefresh takes group g returns nothing
    set Flag = true
    set Refr = g
    call ForGroup(Refr, function AddEx)
    if Flag then
        call GroupClear(g)
    endif
endfunction

function NewGroup takes nothing returns group
    if Count == 0 then
        set Groups[0] = CreateGroup()
    else
        set Count = Count - 1
    endif
    set Status[GetHandleId(Groups[Count])-MIN_HANDLE_ID] = 1
    return Groups[Count]
endfunction

function ReleaseGroup takes group g returns boolean
    local integer stat = Status[GetHandleId(g)-MIN_HANDLE_ID]
    local boolean b    = true
    if g == null then
        debug call BJDebugMsg(SCOPE_PREFIX+" Error: Null groups cannot be released")
        set b = false
    elseif stat == 0 then
        debug call BJDebugMsg(SCOPE_PREFIX+" Error: Group not part of stack")
        set b = false
    elseif stat == 2 then
        debug call BJDebugMsg(SCOPE_PREFIX+" Error: Groups cannot be multiply released")
        set b = false
    elseif Count == 8191 then
        debug call BJDebugMsg(SCOPE_PREFIX+" Error: Max groups achieved, destroying group")
        call DestroyGroup(g)
        set b = false
    else
        call GroupClear(g)
        set Groups[Count]                = g
        set Count                        = Count + 1
        set Status[GetHandleId(g)-MIN_HANDLE_ID] = 2
    endif
    return b
endfunction
endlibrary
А вот её код, ничего особо заумного...
ответ
Всё, довольно быстро разобрался
Помогла функция от quq_CCCP если не ошибаюсь
function CopyGroup takes group g returns group
    set bj_groupAddGroupDest = CreateGroup()
    call ForGroup(g, function GroupAddGroupEnum)
    return bj_groupAddGroupDest
endfunction
Вот так переделал
	...
	local group gg = null
	...
	set TempG = LoadGroupHandle(udg_Hash,i,4)
    set TempReal = LoadReal(udg_Hash,i,3)
    call ForGroup(g,function move1)
    set gg = CopyGroup(TempG)
    call SaveGroupHandle(udg_Hash,i,4,gg)
    call GroupClear(TempG)
    set TempG = null
	...
Хотя вроде каждые 0.03 сек создаётся новая группа, а удаляется лишь один раз вместе с таймером, мне кажется там утечек из-за этого дофига. Но это чуть позже проверю, в таком случае откажусь от ForGroup

Да, к сожалению оно вызывает утечки, но это было очевидно. Копирование группы лучше использовать для локальных групп, которые можно будет потом уничтожить. В общем перенесу всё в луп

Код
private function move takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer i = GetHandleId(t)
    local group g = LoadGroupHandle(udg_Hash,i,0)
    local group gg = CopyGroup(g)
    local group ggg = CreateGroup()
    local group g1 = LoadGroupHandle(udg_Hash,i,4)
    local real d = LoadReal(udg_Hash,i,2)+WavesSpeed
    local real a
    local unit u = null
    local unit uu = null
    
    loop
        set u = FirstOfGroup(gg)
        exitwhen u == null
        set a = GetUnitFacing(u)*bj_DEGTORAD
        call SetUnitX(u,GetUnitX(u)+WavesSpeed*Cos(a))
        call SetUnitY(u,GetUnitY(u)+WavesSpeed*Sin(a))
        set bj_groupEnumOwningPlayer = GetOwningPlayer(u)
        call GroupEnumUnitsInRange(ggg,GetUnitX(u),GetUnitY(u),WaveRadius,Condition(function myfilt))
        set bj_groupEnumOwningPlayer = null
        loop
            set uu = FirstOfGroup(ggg)
            exitwhen uu == null
            if not IsUnitInGroup(uu,g1) then
                call UnitDamageTarget(u,uu,LoadReal(udg_Hash,i,3),true,false,AttackType,DamageType,WeaponType)
                call GroupAddUnit(g1,uu)
            endif
            call GroupRemoveUnit(ggg,uu)
            set uu = null
        endloop
        call GroupRemoveUnit(gg,u)
        set u = null
    endloop
    
    if d >= LoadReal(udg_Hash,i,1) then
    DisplayTextToPlayer(Player(0),0,0,I2S(1))
        call PauseTimer(t)
        call DestroyTimer(t)
        call FlushChildHashtable(udg_Hash,i)
        call ForGroup(g,function kill)
        call GroupClear(g)
        call DestroyGroup(g)
        call GroupClear(g1)
        call DestroyGroup(g1)
    else
        call SaveReal(udg_Hash,i,2,d)
    endif
    
    call DestroyGroup(gg)
    call DestroyGroup(ggg)
    set g = null
    set gg = null
    set ggg = null
    set g1 = null
    set t = null
    set g = null
endfunction

Что это за абилку я делаю, можете посмотреть с 20.12.2020 вечером в моём блоге))
Да, это реклама говноабилок, я лох

23

» WarCraft 3 / Массовая атака

Похожие вопросы:

ответ
Darfilerfis:
Что тут сложного? Сделал за 2 минуты
Сделал через Волну Силы. Или как там
ответ
должен сразу предупредить что делать за тебя никто не будет
теперь по твоим вопросам
  1. чтобы нельзя было кликать скрываешь, даёшь москиты, делаешь видимым
  2. действие проиграть звук и указываешь твою фразу
  3. выбираем всех подходящих(враги,живые) юнитов в радиусе от точки каста и создаём по дамми юниту(юнит без модели, без атаки, с москитами, с нужной способность, время жизни юнита 1 сек) для каждого подходящего юнита приказывая дамми юниту применить нужную способность в подходящего юнита
таким образом каждый дамми юнит применит нужную способность (в твоём случае корни) в 1 подходящего юнита для которого он и был создан а потом исчезнет
  1. система отлова урона
  2. морф юнита либо орбы
всё что я не описал есть в статьях
тебе нужны первые 2 раздела ("Основы" и "Триггеры и объекты")
ответ
на определение сзади ли юнит есть функция
function IsUnitBack takes unit uF, unit uWhichBack returns boolean
        real r1 = bj_RADTODEG * Atan2(GetUnitY(uWhichBack) - GetUnitY(uF), GetUnitX(uWhichBack) - GetUnitX(uF)) + 360.
        real r2 = GetUnitFacing(uWhichBack) + 360.
           if GetUnitY(uWhichBack) < GetUnitY(uF) then
               set r1 = r1 + 360.
           endif
        return (r1<=(r2+45.) and r1>=(r2-45.))
    endfunction
ответ
падает при чистке памяти, строки нигде не перезаписываешь из мемхака? Это точно не с цифрами работа

23

» WarCraft 3 / Отслеживание атаки юнита

Похожие вопросы:

ответ
имхо, легче сделать ее самому, а не отлавливать
ответ
на сколько я понял твой триггер срабатывает при получении урона определённым юнитом
и ты вызываешь в нём этот триггер
который наносит урон этому самому юниту
в результате опять срабатывает отлов урона
и опять наносится урон
и опять ...
в общем получается рекурсия и вар выкидывает из за переполнения стека
кстати почему бы не сделать отлов урона в 1 триггере?
ответ
событие "юнит атакован" срабатывает перед каждой атакой в момент замаха
событие "юнит получает урон" (Specific unit event) срабатывает перед нанесением урона, но это событие нужно добавлять другим триггером отдельно для каждого юнита (Trigger - Add new event)

23

» WarCraft 3 / Кастомная способность

Похожие вопросы:

ответ
Событие EventUnitSummon
GetUnitX\Y от GetSummonedUnit()
ответ
Посмотри код её приказа и отдавай через приказ, в чём проблема?
Способности через GUI только стандартные кастуются и те, что имеют такой же приказ.
ответ
Только дебаффы ядовитых стрел могут стакатся, но даммик обязан иметь дальнюю атаку (при условии что у разных абилок ядовитых стрел будут разные баффы в настройках).
Так же можно юзать таймер и ауру торнадо как написали выше, ну если уж совсем нужен сложный бафф как дефолтный - то тут триггер и немного гемора с мемхаком, зато полный комплект параметров (мигает иконка в статусе перед завершением время действия, бафф спадает с цели после диспела, смерти (у цели крест перерождения или аналог), складывается или не складывается в зависимости от кода).
Пример не рекомендуемый к повторению
function FormatAirportTrainingBar takes integer fp_n returns string
    local string str = ""

    if ( fp_n <= 0 ) then
        return str
    endif

    loop
        exitwhen fp_n < 10
        if ( udg__TempBarStyle == 0 ) then
            set str = str + "''''''''''"
        else
            set str = str + "||||||||||||||||||||"
        endif
        set fp_n = fp_n - 10
    endloop

    loop
        exitwhen fp_n <= 0
        if ( udg__TempBarStyle == 0 ) then
            set str = str + "'"
        else
            set str = str + "||"
        endif
        set fp_n = fp_n - 1
    endloop

    return str
endfunction

function UpdateAirportTrainingBar takes texttag tt, integer fp_nTick, integer fp_nTickMax returns nothing
    local integer nProgress
    local integer nLen
    local string strTT1
    local string strTT2

    if ( tt == null ) then
        call BJDebugMsg( "text tag hDZzRwuZxFQcXqaMPnML null" )
        return
    endif

    set nLen = R2I( I2R( fp_nTickMax ) / 300 * 100 )
    set nProgress = R2I( I2R( nLen ) / fp_nTickMax * fp_nTick )
    set strTT1 = "" + FormatAirportTrainingBar( nProgress )
    set strTT2 = FormatAirportTrainingBar( nLen - nProgress ) + ""
    call SetTextTagText( tt, "|cff0080c0" + strTT1 + "|r|cffff0000" + strTT2 + "|r", 0.023 )
endfunction

function Get_Staff_of_Purification takes unit runner returns item
    set bj_forLoopAIndex = 0
    set bj_lastCreatedItem = null
    
    if GetUnitAbilityLevel( runner, 'Arun' ) == 0 then
        return null
    endif
    
    loop
        exitwhen bj_forLoopAIndex > 5

        set bj_lastCreatedItem = UnitItemInSlot( runner, bj_forLoopAIndex )
        if GetItemTypeId( bj_lastCreatedItem ) == 'I01A' then
            return bj_lastCreatedItem
        endif

        set bj_forLoopAIndex = bj_forLoopAIndex + 1
    endloop

    return bj_lastCreatedItem
endfunction

function Trig_RunnerDamageDetect_Conditions takes nothing returns boolean
    if GetTriggerEventId( ) == EVENT_UNIT_DAMAGED then
        return GetEventDamage( ) > 0.00 and GetEventDamageSource( ) != GetTriggerUnit( ) and GetEventDamageSource( ) != DummyAttacker
    endif
    return true
endfunction

function HealRunner takes nothing returns nothing
    local DamageData dd = GetDataBX( GetExpiredTimer( ) )
    
    call UnitRemoveAbility( dd.attacked, 'AMhp' )
    call SetUnitState( dd.attacked, UNIT_STATE_LIFE, dd.hp )
    
    call RemoveDataBX( dd.trix )
    call DestroyTimer( dd.trix )
    call dd.clear( )
    call dd.destroy( )
endfunction

function Trig_RunnerDamageLock_Actions takes nothing returns nothing
    local TriggerData st = GetDataBX( GetTriggeringTrigger( ) )
    local DamageData dd
    local eventid id = GetTriggerEventId( )
    
    if id == EVENT_GAME_TIMER_EXPIRED and st.id < st.time and st.attacked != null then
        set st.id = st.id + 1
        if GetUnitAbilityLevel( st.attacked, 'Bcyc' ) > 0  or GetUnitAbilityLevel( st.attacked, 'Bcy2' ) > 0 then
            call SetTextTagPos( st.tt, GetUnitX( st.attacked ) - 60.00, GetUnitY( st.attacked ) - 60.00, 585.00 )
        else
            call SetTextTagPos( st.tt, GetUnitX( st.attacked ) - 60.00, GetUnitY( st.attacked ) - 60.00, 80.00 + GetUnitFlyHeight( st.attacked ) )
        endif
        call UpdateAirportTrainingBar( st.tt, 100 - R2I( st.dmg / st.hp * 100.00 ), 100 )
        
    elseif id == EVENT_UNIT_DAMAGED and st.dmg < st.hp then
        set dd = DamageData.create( )
        set dd.trix = CreateTimer( )
        set dd.attacked = st.attacked
        set dd.dmg = GetEventDamage( )
        set dd.hp = GetUnitState( dd.attacked, UNIT_STATE_LIFE )
        
        call SetDataBX( dd.trix, dd )
        call UnitAddAbility( dd.attacked, 'AMhp' )
        call SetUnitState( dd.attacked, UNIT_STATE_LIFE, dd.hp + dd.dmg )
        
        call TimerStart( dd.trix, 0.00, false, function HealRunner )
        
        set st.dmg = st.dmg + dd.dmg
    else
        call UnitRemoveAbility( st.attacked, 'A08L' )
        call UnitMakeAbilityPermanent( st.attacked, false, 'A08L' )
        call DisableTrigger( st.trg )
        call SetTextTagVisibility( st.tt, false )
        
        if not IsUnitDead( st.attacked ) then
            call UnitRemoveAbility( st.attacked, 'B00A' )
        endif
        
        call RemoveSavedInteger( gg_htb_HashData, ExKeySoPRunner, GetHandleId( st.attacked ) )
        
        call st.RemoveTrigger( )
        call st.destroy( )
    endif
    
    set id = null
endfunction

function Trig_Staff_of_Purification_Actions takes nothing returns nothing
    local TriggerData dd
    local unit Runner = GetSpellAbilityUnit( )
    local integer RunnerId = GetHandleId( Runner )
    local item Staff = LoadItemHandle( gg_htb_HashData, RunnerId, ExKeySoP )
    local integer ChargesCount = 0
    local trigger trig = LoadTriggerHandle ( gg_htb_HashData, ExAtomShield, RunnerId )
    local integer pBuff
    
    if Staff == null then
        set Staff = Get_Staff_of_Purification( Runner )
         
        if Staff == null then
            //call DisplayTextToPlayer( Player( CrashPlayerNumber ), 0.00, 0.00, I2Sx( 'A01Q', CrashPlayerNumber ) )
            call BJDebugMsg( DEBUG + I2Sx( 'A02O', 0 ) + INFO )
            return
        endif
        
        call SaveBoolean( gg_htb_HashData, RunnerId, ExKeyHasStaff, true )
        call SaveItemHandle( gg_htb_HashData, RunnerId, ExKeySoP, Staff )
    endif
    
    set ChargesCount = GetItemCharges( Staff )
    
    if ChargesCount < 1 then
        set Runner = null
        set Staff = null
        set trig = null
        return
    endif
    
    call SetItemCharges( Staff, 0 )
    
    if trig != null then // блокирующие урон способности не складываются.
        call TriggerExecute( trig )
        set trig = null
    endif
    
    set dd = TriggerData.create( )
    set dd.attacked = Runner
    set dd.pl = GetOwningPlayer( Runner )
    set dd.trg = CreateTrigger( )
    set dd.trc = TriggerAddCondition( dd.trg, Condition( function Trig_RunnerDamageDetect_Conditions ) )
    set dd.tra = TriggerAddAction ( dd.trg, function Trig_RunnerDamageLock_Actions )
    set dd.tt = CreateTextTag( )
    set dd.hp = 1000.00 * ChargesCount
    set dd.dmg = 1.00
    set dd.id = 0
    set dd.time = 480
    set dd.c = 0.03125
    
    call UnitAddAbility( Runner, 'A07E' )
    call UnitRemoveAbility( Runner, 'A07E' )
    call UnitAddAbility( Runner, 'A08L' )
    call UnitMakeAbilityPermanent( Runner, true, 'A08L' )
    
    call SetDataBX( dd.trg, dd )
    call SaveInteger( gg_htb_HashData, ExKeySoPRunner, RunnerId, dd )
    
    call TriggerRegisterPlayerEvent( dd.trg, dd.pl, EVENT_PLAYER_LEAVE )
    call TriggerRegisterDeathEvent( dd.trg, Runner )
    call TriggerRegisterUnitEvent( dd.trg, Runner, EVENT_UNIT_DAMAGED )
    
    call TriggerRegisterTimerEvent( dd.trg, 0.03125, true )
    
    if GetLocalPlayer( ) == dd.pl or IsPlayerAlly( GetLocalPlayer( ), dd.pl ) then
        call SetTextTagVisibility( dd.tt, true )
    else
        call SetTextTagVisibility( dd.tt, false )
    endif
    
    set pBuff = GetUnitAbility( dd.attacked, 'B00A' ) + 0x90
    set dd.c = TimerGetElapsed( DispTimer )
    call WMem( RMem( pBuff ) + 0x4, mR2I( dd.c + 15.10 ) )
    call WMem( RMem( pBuff ) + 0x8, mR2I( dd.c + 10.408 ) )
    call SetBuffLevel( pBuff - 0x90, ChargesCount )
    call UpdateAirportTrainingBar( dd.tt, 100, 100 )
    
    set Runner = null
endfunction
    
//===========================================================================
function InitTrig_Staff_of_Purification takes nothing returns nothing
    set udg__TempBarStyle = 0
endfunction
Выше пример баффа для предмета, который образует щит блокирующий урон, кол-во заблокированного урона и сколько еще заблокирует щит отображается над головой героя, в виде полоски здоровья (только цвет сине-красный). Так же в статуе есть бафф, один в 1 как бафф дефектных способностей вара, не складывается - новый, перебивает старый. И так далее...
ответ
Ответ простой, это beta.
ответ
Про какой таймер ты говоришь? Ты джасс учишь? Локальный таймер? Или тот, что на гуи?

23

» WarCraft 3 / Часто карты не запускаются

Похожие вопросы:

ответ
поиск юзал? я внятного ответа не нашел, но вообще-то пишут, что там картинку вставляют
"war3mapMap.blp" у ее еще размер нужно норм поставить, путь не знаю точно какой еще надо приписывать. и нужно ли
вроде этой функцией, не знаю
native SetAltMinimapIcon takes string iconPath returns nothing
я видел в одной из близзадской ТД-шке. Там еще разворачивают камеру. Посмотрю
смотри Замок Скиди
ответ
скачай этот файл и закинь его в папку AdicHelper\lib\ в папке с jngp
после в шапке карты напиши include "ifdebug.j"
и создай триггер с событием
игрок написал в чат ifdebug как точное совпадение
действие
кастом скрипт log()
после чего запусти карту и напиши в чат ifdebug
он выведет на экран все if/else/elseif через которые он прошёл (true в скобках в конце строки означает что значение в ифе истина)
ответ
похоже более всего на мусор, попадающий в память откуда-то извне. Обычно пропущенная строка автокаста такой фигней страдает. Нельзя точно сказать, нужно менять поля и смотреть. К счастью, описания можно менять и локально, не перепаковывая карту
ответ
Если есть тимвиверные лаги, есть ещё миллион других программ для удалёнки, AnyDesk или Spleshtop (вроде платный, но это не проблема)
Но я делал по другому: по впн цеплялся домой на роутер, на домашнем компе на Win 10 pro создавал второго пользователя (в принципе можно и создавать и не патчить десятку под сервер), подключался через удалённый рабочий стол к домашнему компу и в принципе всё, vpn соедение на убунте хз где, но remmina для удалённого рабочего стола есть точно, ну или параллелс десктоп в режиме rdp.
Если ничего не понятно, то могу подробно расписать что и как я делал
Так же никто не отменял поставить варик на любой комп в рабочей сети (если есть доступ на такие пакости), хоть на компьютер бухглатера и в режиме второго пользователя сидеть по RDP на этом компе, WE вроде сильно не грузит =)

23

» WarCraft 3 / Механика босса

Похожие вопросы:

ответ
Смотрите код main после сохранения карты, там походу где то обрыв потока...
ответ
я за, только скорее всего
на денежной основе
потому шо идей у самого тонны
Ну а вообще глянуть бы ещё что там у тебя за мапа и что за заклинания и что к чему
И какая версия варика?
Если для 1.26, то NOPE, а если выше то пиши в лс, кинь мапу и сразу распиши поподробнее что к чему, лучше в ВК

23

» WarCraft 3 / Выбор варианта здания

Похожие вопросы:

ответ
Видимо єта кнопка тесно спряжена с более низкими слоями игры (чит. "hardcoded"). Похоже, что скрыть её нельзя. Я могу только посоветовать вернуться назад и посмотреть, что можно сделать по-другому, чтобы не приходилось скрывать кнопку.
Melissa:
Units\commandstrigs.txt
Units\commandfunc.txt
Порыть там надо, во всяком случае стандартные приказы, иконки и клавиши к ним там прописаны.
(естесственно нужно импоритровать эти изменённые файлики в карту)
Я пробовал прописывать кнопке неадекватные значения позиции кнопки и пиктограммы, но ничего не вышло — игра подставляет свои значения.
ответ
Таурен Тауреныч, точнее не блокировать, а прятать улучшения (если про улучшения говорим).
пример
Объяснение: Вот нажали, и текущее исследование запущено. Мы ловим начало и завершение этого исследования. Есть три апгрейда, и если выбрано одно из них, то два остальных блочат. Если прерывают через кнопку отмена, то нужно все вернуть как было
Событие - Игрок начинает улучшение
Действие - То блокировать остальные улучшения игрока (через вкладку Игрок делаешь max уровень улучшения ставишь на ноль, тогда игрок не сможет выбрать еще одно)
Событие - Игрок прекращает (прерывает) улучшение (это когда нажимает на отмену) Еще надо проверить, срабатывает ли событие это при уничтожении лаборатории (здания) в тот момент, когда что-то изучает. Если нет, тогда придется добавить в триггер событие "Юнит умирает"
Действие - То вернуть как было.
Событие - Игрок завершает улучшение (короче успешно завершено, никак не откатишь улучшение)
Действие - Тут ..... (ваше действие) подчищаем все и др.

23

» WarCraft 3 / Цикл способности

Похожие вопросы:

ответ
вейт и цикл не будут работать правильно. никак. и этого никак не сделать.
100 раз уже мусолили тему
сделай еще триг на включение.выключение таймера
ответ
получение текущего приказа не требует от тебя нихера, тебе нужно, чтобы там не было "useitem", и всё
ответ
Pick every unit in range [250] matching condition [бафф спелла]
Всё что находится внутри данного блока произойдёт столько раз, сколько воинов находится внутри выбранной группы. Обратиться к воину можно через Picked Unit ( GetEnumUnit( ) ). Если Вам нужно добавить событие на смерть именно этих воинов, то прямо здесь внутри блока добавляете их в событие триггера, выбрав их через Picked Unit, или сохраняете их в переменные.

Также можно не сохранять каждого воина, а занести их в отдельную группу. А вместо проверки:
Условие: Dying unit = Aim [Integer A]
проверяете, находится ли воин в группе.
ответ
Вот держи. За подробностями в вк можешь обратится и если такое дело помогу доработаю систему на jass ( мой вк - vk.com/id446544976 )
ответ
~8gabriel8:
Убрал Ждать из действий внутри отряда, вестимо)

Труп-это мёртвый юнит, а не декорация.

23

» WarCraft 3 / Конверт моделей

Похожие вопросы:

ответ
Infernall, ты просил чтобы ктото приготовил суп за тебя
за бесплатно это никто не будет делать
за бесплатно только советы есть
ответ
закрыт по таймауту
ответ
Скорее всего модель из версии WoW старше пылающего легиона для таких случае скачай 3Ds max и плагин Neodex и переведи модель в формат mdx.
ответ
Забросил, не нашел программы.
ответ
Копать в сторону глобальной анимации век

23

» WarCraft 3 / Морф героя

Похожие вопросы:

ответ
Лучший вариант - морф через руну
ответ
quq_CCCP:
без морфов то у тебя и нет вариантов сохранить все праметры, список баффов, кулдауны абилок и прочее ты никак иначе не сохранишь.
и не надо, чел как бы меняет полностью героя. Единственное что надо сохранить это хп и ману. А герой сбрасывается до 1 лвла
ответ
ПС. Давать спеллбук после найма (чтобы он сам пропадал после морфа) героя нельзя, ибо в этом случае, если герой не успел или не захотел выбрать талант, то у него пропадает такая возможность после морфа.
Делать нужно именно так. И что бы у тебя не было здесь ошибки, тебе нужно каким-либо образом обозначить то, что у героя есть непотраченный талант. Т.е. ты будешь давать герою спеллбук после морфа, если у него есть доступные очки талантов.
И ещё кое-что: если ты триггерно даёшь спеллбук и пермоментишь его (тоже триггерно), то после морфа он не пропадаёт, а если ты его отнимаешь - он не возвращается (т.е. нету лишних ненужных появлений/исчезновений абилки).
А так же смотри что бы спеллбук не остался пустым, решается это пермоментом абилок внутри спеллбука.
ответ
Extremator, я допустил глупейшую ошибку. Случайно делал перманентными не те способности. Спасибо за ответ и сорри за вопрос.
ответ
Frostfall:
Что за вариант с рунами? Первый раз про такой слышу вообще.

Frostfall:
А можно ли будет такой морф Друида навязать на айтем?
Ну примерно это и происходит по ссылке выше
Frostfall:
А почему тёмный лучше не юзать? Что с ним плохого может быть?
У абилки много спецификации, и её нужно понимать.
Если делать на-абум, будут баги либо вообще фаталы.